package org.lonetree.tc.core;

import org.lonetree.tc.core.id.InternalIdentifiableItem;
import org.lonetree.tc.core.id.NumericalId;

/**
 * Business class representing sources for books in the system.
 * 
 * All interfaces between different system components should use objects of this
 * class to pass information about sources.
 */
public abstract class Source extends InternalIdentifiableItem{
	
	private Book parentBook;
	private String name;
	private float price;
	private String description;
	
	protected Source(SourceId sourceId, Book parentBook, String name, float price, String description){
		super(sourceId);
		
		if(parentBook == null)
			throw new NullPointerException("parentBook cannot be null");
		
		if(name == null)
			throw new NullPointerException("name cannot be null");
		if(name.trim().equals(""))
			throw new NullPointerException("name cannot be empty");

		if(price < 0)
			throw new NumberFormatException("price cannot be less than 0");
		
		
		this.name = name.trim();
		this.price = price;
		this.parentBook = parentBook;
		parentBook.getSources().add(this);
		
		if(description == null)
			this.description = description;
		else
			this.description = description.trim();
	}
	
	/**
	 * Get the SourceId identifying the source.
	 *
	 * @return SourceId
	 */
	public SourceId getSourceId(){
		return (SourceId)getIdentifier();
	}

	/**
	 * Get the book this is a source for.
	 *
	 * @return parent book
	 */
	public Book getParentBook(){
		return parentBook;
	}

	/**
	 * Get the name of the source.
	 *
	 * @return name
	 */
	public String getName(){
		return name;
	}
	
	/**
	 * Get the price the source is offering the book for.
	 *
	 * @return price
	 */
	public float getPrice(){
		return price;
	}

	/**
	 * Get the description of the source.
	 *
	 * @return description
	 */
	public String getDescription(){
		return description;
	}
	
	@Override
	protected String getIdentifierType(){
		return "sourceId";
	}
	
	/**
	 * ValidatedIdentifier representing a source. Since sources have identifiers
	 * that are only meaningful internally, SourceIds are numerical.
	 */
	public static class SourceId extends NumericalId{

		/**
		 * Create a SourceId encapsulating the numericalId.
		 *
		 * @param numericalId - the numerical ID
		 * @throws ValidationExceptions are never thrown
		 */
		public SourceId(Long numericalId) throws ValidationException{
			super(numericalId, INFINITE_LENGTH_ALLOWED);
		}
		
		/**
		 * Create a SourceId encapsulating the numericalId.
		 *
		 * @param numericalId - the String containing the numerical ID
		 * @throws ValidationException if the numericalId contains characters
		 * 							   other than numbers
		 */
		public SourceId(String numericalId) throws ValidationException{
			super(numericalId);
		}
		
		/**
		 * Get the String representation of the source ID.
		 *
		 * @return source ID
		 */
		public Long getSourceIdLong(){
			return getNumericalIdLong();
		}
	}
}
